/**
 * 取样器
 * 
 */
class Sampler {

    /**
     * HTTP请求
     * 
     * @param {XMLBuilder} parent 
     * @param {{testname: String, comment: String, protocol: String, host: String, port: String, method: String, path: String, request: Object}} config 
     * @returns {XMLBuilder}
     */
    createHttpRequest(parent, config = { testname: "Http Request", comment: "", protocol: "", host: "", port: "", path: "", method: "", request: null }) {
        const { testname, comment, protocol, host, port, path, method, request } = config;
        const jmxHttpRequest = parent.ele("HTTPSamplerProxy", { guiclass: "HttpTestSampleGui", testclass: "HTTPSamplerProxy", testname });
        jmxHttpRequest.ele("stringProp", { name: "TestPlan.comments" }).txt(comment).up()
            .ele("stringProp", { name: "HTTPSampler.domain" }).txt(host).up()
            .ele("stringProp", { name: "HTTPSampler.protocol" }).txt(protocol).up()
            .ele("stringProp", { name: "HTTPSampler.port" }).txt(port).up()
            .ele("stringProp", { name: "HTTPSampler.method" }).txt(method).up()
            .ele("stringProp", { name: "HTTPSampler.contentEncoding" }).txt("UTF-8").up()
            .ele("boolProp", { name: "HTTPSampler.follow_redirects" }).txt("true").up()
            .ele("boolProp", { name: "HTTPSampler.use_keepalive" }).txt("true");
        if (method === "GET" && request) {
            const queryString = Object.keys(request).map(key => `${key}=${request[key]}`).join('&');
            jmxHttpRequest.ele("stringProp", { name: "HTTPSampler.path" }).txt(`${path}?${queryString}`);
        } else {
            jmxHttpRequest.ele("stringProp", { name: "HTTPSampler.path" }).txt(path);
        }
        if (method === "POST") {
            jmxHttpRequest.ele("boolProp", { name: "HTTPSampler.postBodyRaw" }).txt("true").up()
                .ele("elementProp", { name: "HTTPsampler.Arguments", elementType: "Arguments" })
                .ele("collectionProp", { name: "Arguments.arguments" })
                .ele("elementProp", { name: "", elementType: "HTTPArgument" })
                .ele("boolProp", { name: "HTTPArgument.always_encode" }).txt("false").up()
                .ele("stringProp", { name: "Argument.value" }).txt(JSON.stringify(request, null, "\t")
                    .replace(/"\$\{([^@}]+)@number\}"/g, "${$1}")// 处理number
                    .replace(/"(\d{4}-\d{2}-\d{2})(( \d{2}:\d{2}:\d{2})?)"/g, (match, datePart, timePart) => {
                        if (datePart === new Date().toISOString().split("T")[0]) {
                            return `"\${__time(yyyy-MM-dd,)}${timePart || ""}"`;
                        }
                        return match;
                    })// 处理日期
                    .replace(/\\\\\\/g, "\\\\\\\\\\"))
                .up()
                .ele("stringProp", { name: "Argument.metadata" }).txt("=")
        }
        const jmxHttpRequestHashTree = jmxHttpRequest.up().ele("hashTree");
        return jmxHttpRequestHashTree;
    }

    /**
     * JSR223 Sampler
     * 
     * @param {XMLBuilder} parent 
     * @param {{testname: String, comments: String, script: String}} config 
     * @returns {XMLBuilder}
     */
    createJsr223Sampler(parent, config = { testname: "JSR223 Sampler", comments: "", script: "" }) {
        const { testname, comments, script } = config;
        const jmxJsr223Sampler = parent.ele("JSR223Sampler", { guiclass: "TestBeanGUI", testclass: "JSR223Sampler", testname: testname });
        jmxJsr223Sampler.ele("stringProp", { name: "cacheKey" }).txt("true").up()
            .ele("stringProp", { name: "filename" }).txt("").up()
            .ele("stringProp", { name: "parameters" }).txt("").up()
            .ele("stringProp", { name: "script" }).txt(script).up()
            .ele("stringProp", { name: "scriptLanguage" }).txt("groovy").up()
            .ele("stringProp", { name: "TestPlan.comments" }).txt(comments);
        const jmxJsr223SamplerHashTree = jmxJsr223Sampler.up().ele("hashTree");
        return jmxJsr223SamplerHashTree;
    }

    /**
     * 调试取样器
     * 
     * @param {XMLBuilder} parent 
     * @param {{testname: String, comments: String}} config 
     * @returns {XMLBuilder}
     */
    createDebugSampler(parent, config = { testname: "JSR223 Sampler", comments: "" }) {
        const { testname, comments } = config;
        const jmxDebugSampler = parent.ele("DebugSampler", { guiclass: "TestBeanGUI", testclass: "DebugSampler", testname: testname });
        jmxDebugSampler.ele("boolProp", { name: "displayJMeterProperties" }).txt("false").up()
            .ele("boolProp", { name: "displayJMeterVariables" }).txt("true").up()
            .ele("boolProp", { name: "displaySystemProperties" }).txt("false").up()
            .ele("stringProp", { name: "TestPlan.comments" }).txt(comments);
        const jmxDebugSamplerHashTree = jmxDebugSampler.up().ele("hashTree");
        return jmxDebugSamplerHashTree;
    }

}

module.exports = Sampler;

